#ifndef QOBJECT_SHADOW_WORLD_H
#define QOBJECT_SHADOW_WORLD_H

#include <QObject>
#include <memory>
#include <QVariant>

#include "QRemoteObjectAdvance_global.h"
#include "QRemoteObject2.h"
#include "QROInterface.h"
/*
当客户端对象属性改变时，不会作出任何反应
当服务端发出属性同步事件时，客户端的对象属性会同步为服务端的属性
当客户端调用pushProperty后，它会向服务端发送一个请求，当服务端接收到请求后若请求合法则会更新服务端属性。但不会立即将属性同步到客户端
*/

/*
当服务端注销一个对象时，客户端会注销对应的对象并析构掉对象。
如果在服务端注销对象前，客户端主动将对象注销掉，服务端再注销时客户端对象不会被析构掉
*/

class QRemoteObject2;

//客户端
class QREMOTEOBJECTADVANCE_EXPORT QRONode:public QObject,public QROInterface
{
    Q_OBJECT
    Q_CLASS_NAME(QRONode)
public:
    QRONode();
    ~QRONode();

    Q_INVOKABLE void connectToHost(QString host,QVariant var = {});

    //将对象注销
    Q_INVOKABLE void unregisterObject(QObject* obj);

    //客户端已和服务端连接完成,并完成了初始对象的链接和初始化
    Q_SIGNAL void connected();

    //客户端连接失败
    Q_SIGNAL void connectFailed();

    //客户端的对象与服务端的对象产生了链接(具体到每个子对象，不管是静态还是动态链接）
    Q_SIGNAL void objectLinked(QObject* obj);
    //某对象断开链接（可能是服务端离线了对象，也可能是客户端注销或析构了对象）
    Q_SIGNAL void objectDislinked(QObject* obj);
    //占领或释放了某对象
    Q_SIGNAL void occupiedObject(QObject* obj);
    Q_SIGNAL void releasedObject(QObject* obj);

    //获取当前被占领的对象
    QObject* getOccupiedObject();

public:
    struct Private;
private:
    void activeMethod(QObject* target,int method,QVariantList param,QRemoteObject2::InvokeCallBack callBack) override;
    void pushProperty(QObject* target,int prop,QVariant value) override;
    void pushParent(QObject* target,QObject* parent) override;
    void occupyObject(QObject* target) override;
    void releaseObject(QObject* target) override;
private:
    Private* _P;
    friend class QRemoteObject2;
};


#endif
